<?php

class Form {

	function __construct($name,$method='post',$stack=true,$attrs=array()) {
		$this->name = $name;
		$this->method = $method;
		$this->stack = $stack;
		$this->attrs = $attrs;
		if(isset($this->attrs['enctype'])) {
			$this->enctype = $this->attrs['enctype'];
		}
		$this->body = null;
	}

	private function add($data) {
		$this->body = $this->body.$data;
	}

	public function setClass($class_name) {
		$this->attrs['class'] = $class_name;
	}

	public function build() {
		if(isset($this->enctype)) {
			$enctype = " enctype='$this->enctype'";
		} else {
			$enctype = '';
		}
		if($this->stack == true) {
			$id = generateId($this->name);
			$div_attrs = $this->getAttrString($this->attrs);
			$start = "<div id='$id' $div_attrs><form name='$this->name' method='$this->method'$enctype>";
			$end = "</form></div>";
		} else {
			$start = "<form name='$this->name' method='$this->method'$enctype>";
			$end = "</form>";
		}
		return $start.$this->body.$end;
	}

	private function mergeAttrs($attrs=array()) {
		$merged_attrs = $attrs;
		if(isset($attrs)) {
			foreach ($attrs as $key => $value) {
				if (strtolower($key) == 'class') {
					if($merged_attrs[$key] != $value)
					$value = $merged_attrs[$key] . ' ' . $value;
				} else if (strtolower($key) == 'style') {
					if($merged_attrs[$key] != $value)
					$value = $merged_attrs[$key] . ';' . $value;
				}
			}
			$merged_attrs[$key] = $value;
		}
		return $merged_attrs;
	}

	private function getAttrString($attrs=array()) {
		$attr_pairs = array();
		if(isset($attrs)) {
			foreach ($attrs as $name => $value) {
				$value = htmlentities($value, ENT_QUOTES);
				$attr_pairs[] = "$name=\"$value\"";
			}
		}
		return join(' ', $attr_pairs);
	}

	public function divStart($name,$attrs=array(),$stack=true) {
		$id = generateId($name);
		if($stack == false) {
			if(isset($attrs['class'])) {
				$attrs['class'] = $attrs['class'].' inline';
			} else {
				$attrs['class'] = 'inline';
			}
		}
		$attr_string = $this->getAttrString($attrs);
		$this->add("<div id='$id' $attr_string");
	}

	public function divEnd() {
		$this->add("</div>");
	}

	public function text($data) {
		$this->add($data);
	}

	public function textInput($name,$label,$attrs=array(),$stack=true) {
		$id = generateId($name);
		$type = isset($attrs['type'])? $attrs['type'] : 'text';
		if(isset($attrs['description'])) {
			$description = $attrs['description'];
			unset($attrs['description']);
		} else {
			$description = '';
		}
		if(isset($attrs['class'])) { $div['class'] = $attrs['class']; unset($attrs['class']); }
		if(isset($attrs['style'])) { $div['style'] = $attrs['style']; unset($attrs['style']); }
		if(isset($attrs['required'])) {
			if($attrs['required'] == true) {
				$required = "<span class='required'>*</span>";
			} else {
				$required = '';
			}
			unset($attrs['required']);
		} else {
			$required = '';
		}
		if(isset($div)) {
			$div_string = $this->getAttrString($this->mergeAttrs($div));
		} else {
			$div_string = '';
		}
		$attr_string = $this->getAttrString($attrs);
		$labelStr = $label === ''? '' : "<label id='lbl-$id' for='$id'>$label: </label>";
		$body =	"$labelStr
			<input id='$id' name='$name' type='$type' $attr_string>
			$required
			<span id='validate-$id' class='invisible hover'></span>
			$description";
			if($stack === true) {
				$this->add("<div id='row-$id' $div_string>$body</div>");
			} else {
				$this->add($body);
			}
	}

	public function textArea($name,$label,$rows,$cols,$attrs=array(),$stack=true) {
		$id = generateId($name);
		if(isset($attrs['description'])) {
			$description = $attrs['description'];
			unset($attrs['description']);
		} else {
			$description = '';
		}
		if(isset($attrs['class'])) { $div['class'] = $attrs['class']; unset($attrs['class']); }
		if(isset($attrs['style'])) { $div['style'] = $attrs['style']; unset($attrs['style']); }
		if(isset($attrs['value']) && $attrs['value'] != '') {
			$value = $attrs['value'];
			unset($attrs['value']);
		} else {
			$value = '';
		}
		if(isset($div)) {
			$div_string = $this->getAttrString($this->mergeAttrs($div));
		} else {
			$div_string = '';
		}
		$attr_string = $this->getAttrString($attrs);
		$labelStr = $label === ''? '' : "<label id='lbl-$id' class='textarea' for='$id'>$label: </label>";
		$body =	"$labelStr
			<textarea id='$id' name='$name' rows='$rows' cols='$cols' $attr_string>$value</textarea>
			<span id='validate-$id' class='invisible hover'></span>
			$description";
			if($stack === true) {
				$this->add("<div id='row-$id' $div_string>$body</div>");
			}
			else {
				$this->add($body);
			}
	}

	public function button($name,$label,$attrs=array(),$stack=true) {
		$id = generateId($name);
		if($stack == true) {
			if(isset($attrs['class'])) { $div['class'] = $attrs['class']; unset($attrs['class']); }
			if(isset($attrs['style'])) { $div['style'] = $attrs['style']; unset($attrs['style']); }
			if(isset($div)) {
				$div_string = $this->getAttrString($this->mergeAttrs($div));
			} else {
				$div_string = '';
			}
		}
		if(!isset($attrs['type'])) {
			$attrs['type'] = 'submit';
		}
		$attr_string = $this->getAttrString($attrs);
		$body = "<input id='$id' name='$name' $attr_string value='$label'>";

		if($stack === true) {
			$this->add("<div id='row-$id' $div_string>$body</div>");
		} else {
			$this->add($body);
		}
	}

	public function anchorButton($name,$label,$href,$attrs=array()) {
		$id = generateId($name);
		if(isset($attrs['class'])) {
			$attrs['class'] = $attrs['class'].' btn';
		} else {
			$attrs['class'] = 'btn';
		}
		$attr_string = $this->getAttrString($attrs);

		$body = "<a href='$href' $attr_string>$label</a>";
		$this->add($body);
	}

	public function fileUpload($name,$label,$attrs=array(),$stack=true) {
		$this->enctype = "multipart/form-data";
		$attrs['type'] = 'file';
		$this->textInput($name,$label,$attrs,$stack);
	}

	public function radioButton($name,$label,$value,$attrs=array(),$stack=true) {
		$attrs['type'] = 'radio';
		$attrs['value'] = $value;
		$attrs['description'] = $label;
		$name .= "-$value";
		$this->textInput($name,'',$attrs,$stack);
	}

	public function selectStart($name,$label='',$attrs=array(),$stack=true) {
		$id = generateId($name);
		$labelStr = $label === ''? '' : "<label id='lbl-$id' class='textarea' for='$id'>$label: </label>";
		if($stack == true) {
			if(isset($attrs['class'])) { $div['class'] = $attrs['class']; unset($attrs['class']); }
			if(isset($attrs['style'])) { $div['style'] = $attrs['style']; unset($attrs['style']); }
			if(isset($div)) {
				$div_string = $this->getAttrString($this->mergeAttrs($div));
			} else {
				$div_string = '';
			}
		}
		$attr_string = $this->getAttrString($attrs);
		if($stack == true) {
			$this->add("<div id='row-$id' $div_string>$labelStr <select id='$id' name='$name' $attr_string>");
		} else {
			$this->add("$labelStr <select id='$id' name='$name'>");
		}
	}

	public function selectEnd($stack=true) {
		if($stack == true) {
			$this->add('</select></div>');
		} else {
			$this->add('</select>');
		}
	}

	public function selectOption($name, $label, $attrs=array()) {
		$id = generateId($name);
		if(isset($attrs['selected'])) {
			if($attrs['selected'] == true) {
				$selected = 'selected';
			} else {
				$selected = '';
			}
			unset($attrs['selected']);
		} else {
			$selected = '';
		}
		$attr_string = $this->getAttrString($attrs);
		$body = "<option id='$id' name='$name' value='$name' $selected $attr_string>$label</optiop>";
		$this->add($body);
	}
}